/**
 * @file main.c
 * @date 23.04.30
 * @author xin
 * @brief 从start.c(start())执行mret跳转而来，当前为S模式
 * @brief 具有main函数，负责各个模块的初始化
 * @version 0.1
 * @status Stable
*/

#include "types.h"
#include "defs.h"
#include "riscv.h"

volatile static int started = 0;    // 当前是否为0号cpu

/**
 * @brief 对各个模块进行初始化
 *        完成后调用调度器进行进程调度
*/
void
main()
{
    if (cpuid() == 0) {
        consoleinit();                      // 初始化中断
        printfinit();                       // 初始化打印
        printf("\n");
        printf("now kernel is booting\n");
        printf("\n");
        kinit();                            // 初始化物理页分配
        kvminit();                          // 创建内核页表
        kvminithart();                      // 启用虚拟内存
        procinit();                         // 初始化进程表
        trapinit();                         
        trapinithart();     
        plicinit();
        plicinithart();
        binit();                            // 初始化磁盘缓存
        iinit();
        fileinit();
        virtio_disk_init();                 // 初始化virtio mmio几个缓冲区描述符
        userinit();                         // 第一个进程&第一个程序
        __sync_synchronize();               // memory barier 内存屏障
        started = 1;
    } else {
        // 等待0号CPU初始化完成
        while (started == 0);
        __sync_synchronize();
        printf("hart %d starting\n", cpuid());
        kvminithart();
        trapinithart();
        plicinithart();
    }

    // 开始调度
    scheduler();
}
